#include <math.h>
#include "fixed.h"
#include "util.h"
 
float clampf(float val, float min, float max) {
	if(val < min) {
		return min;
	} else if(val > max) {
		return max;
	}
	return val;
}

int clamp(int val, int min, int max) {
	if(val < min) {
		return min;
	} else if(val > max) {
		return max;
	}
	return val;
}

fixedp clampq(fixedp val, fixedp min, fixedp max)
{
	if(val < min) {
		return min;
	} else if(val > max) {
		return max;
	}
	return val;
}

short mean(short *buf, int len)
{
	int sum = 0;
	for(int i = 0; i < len; i++) {
		sum += buf[i];
	}
	return (short)(sum / len);
}

fixedp qmean(fixedp *buf, int len)
{
	fixedp sum = 0;
	for(int i = 0; i < len; i++) {
		sum += buf[i];
	}
	return qdiv(sum, int2q(len));
}

float maxf(const float *buf, int *i, int len)
{
	float max = buf[0];
	int maxI = 0;
	for(int i = 0; i < len; i++) {
		if(buf[i] > max) {
			max = buf[i];
			maxI = i;
		}
	}
	*i = maxI;
	return max;
}

void mydft(const short *x, float *out, int N)
{
	for(int k = 0; k < N/2; k++) {
		// X[k] = sum(x[n] * exp(-j*2*pi*k*n/N))
		float rsum = 0, isum = 0;	// real and imaginary accumulation variables
		for(int n = 0; n < N; n++) {
			// exp(-2*pi*j*k*n/N) = cos(2*pi*k*n/N) - j*sin(2*pi*k*n/N)
			rsum += (float)x[n] * cosf(2*M_PI*k*n/(float)N);
			isum += (float)x[n] * -sinf(2*M_PI*k*n/(float)N);
		}
		// X[k] = a + jb
		// abs(X[k]) = sqrt(a^2 + b^2);
		out[k] = sqrtf(rsum * rsum + isum * isum);
	}
}


const char *int2str(int i)
{
	static char buf[16];

	char *p = buf + 15;
	*p = 0;

	if (i < 0)
	{
		do
		*--p = '0' - i % 10;
		while ((i /= 10) != 0);

		*--p = '-';
	}
	else
	{
		do
		*--p = '0' + i % 10;
		while ((i /= 10) != 0);
	}

	return p;
}
